<?php

class Model_Category extends Ac_Model
{

   const TYPE = 2;
   protected static  $_collection = 'category';

   const STATUS_ACTIVE  = 1;
   const STATUS_DELETED = 6;

   const LISTING_RECENT_LIMIT  = 12;
   const LISTING_POPULAR_LIMIT = 12;

    /**
     *
     * @var array define the requirements for this model
     */
    protected static $_requirements = array(
     //   'em'  => array('Required', 'Validator:EmailAddress'), //Email
        'path'  => array('Array'), //category
    );

    protected static $_transcript = array(
        '_id'       => '_id',
        'path'      => 'path',
        'nm_en'     => 'name_en',        
        'nm_tc'     => 'name_tc',
        'nm_sc'     => 'name_sc',
        'nav_nm_en' => 'nav_name_en',
        'nav_nm_tc' => 'nav_name_tc',        
        'nav_nm_sc' => 'nav_name_sc',        
        'lc'        => 'listing_count',
        'pt_en'     => 'page_title_en',
        'pt_tc'     => 'page_title_tc',
        'pt_sc'     => 'page_title_sc',
        'ds_en'     => 'description_en',
        'ds_tc'     => 'description_tc',
        'ds_sc'     => 'description_sc',
        'bl_en'     => 'blurb_en',
        'bl_tc'     => 'blurb_tc',
        'bl_sc'     => 'blurb_sc',
        'so_en'     => 'sold_en',
        'so_tc'     => 'sold_tc',
        'so_sc'     => 'sold_sc',
        'mt'        => 'moved_to',
        'sa'        => 'status',
        'pr'        => 'price_range',
    );

    public function __construct($data = array(), $config = array())
	{
        $config['collection'] = 'category';
        self::ensureIndex(array('_type' => 1));
        self::ensureIndex(array('pos' => 1));
        self::ensureIndex(array('path' => 1));
        self::ensureIndex(array('url_en' => 1));
        self::ensureIndex(array('url_tc' => 1));
        parent::__construct($data, $config);
    }

    
    public function __get($name)
    {
        if ($name == 'page_title') {
            $current_language = Zend_Registry::get('current_language');
            return parent::__get('page_title_'.$current_language);
        } elseif ($name == 'description') {
            $current_language = Zend_Registry::get('current_language');
            return parent::__get('description_'.$current_language);
        } elseif ($name == 'name') {
            $lang = Zend_Registry::get('current_language');
            return parent::__get('nm_'.$lang);
        } elseif ($name == 'nav_name') {
            $lang = Zend_Registry::get('current_language');
            return parent::__get('nav_nm_'.$lang);            
        } elseif ($name == 'blurb') {
            $lang = Zend_Registry::get('current_language');
            return parent::__get('blurb_'.$lang);
        } elseif ($name == 'sold') {
            $lang = Zend_Registry::get('current_language');
            $res = parent::__get('sold_'.$lang);
            if (empty($res)) {
                $res = 'Sold';
            }
            return $res;
        } else {
            return parent::__get($name);
        }   
    }
    
    public function __isset($name) {
        $val = self::__get($name);
        return!empty($val) ? true : parent::__isset($name);
    }
    
    public function getLevel()
    {
        return count($this->path);
    }

    public static function getLevel1($arr = array())
    {
        return self::all($arr + array('sa'=>1, 'path' => array('$size' => 1)));
    }

    public static function getLevel2($arr = array())
    {
        return self::all($arr + array('path' => array('$size' => 2)))->sort(array('path' => 1));
    }

    public static function getLevel3($arr = array())
    {
        return self::all($arr + array('path' => array('$size' => 3)))->sort(array('path' => 1));
    }

    public function getParent()
    {
        if (count($this->path)>1) {
            return Model_Category::find($this->path[count($this->path) - 2]);
        }
    }

    public function getParentTree()
    {
        $res = array();
        foreach($this->path as $cat) {
            $res[] = Model_Category::find($cat);
        }
        return $res;
    }

    public function getChildren($all = false, $params = array())
    {
        if ($all) {
            $criteria = array_merge($params, array('path' => $this->_id, '_id'=>array('$ne' => $this->_id)));
        } else {
            $criteria = array_merge($params, array('path.'.($this->getLevel()-1) => $this->_id, 'path' => array('$size' => ($this->getLevel()+1))));
        }
        $it = self::all($criteria);
        return $it;
    }

    public function countListings()
    {
        $children = $this->getChildren(true);
        $cat = array();
        foreach($children as $child) {
            $cat[] = $child->_id;
        }
        return Model_Listing::all(array('ca' => array('$in' => $cat)))->count();
    }

    public function url($full_url = false, $force_lang = null)
    {
        $cache = Zend_Registry::get('cache');
        $current_language = Zend_Registry::get('current_language');
        $key = 'category_url_'.$this->_id.'_'.$current_language.'_'.(int)$full_url.'_'.(int)$force_lang;
        if (!$res = $cache->load($key)) {        
            $view = Zend_Registry::get('Zend_View');
            $params = array('category' => $this);
            if ($force_lang !== null) {
                $params = array_merge(array('lang' => $force_lang), $params);
            }
            $res = ($full_url ? 'http://'.REGULAR_DOMAIN:'') . $view->geturl('display', 'category', $params);
            $cache->save($res, $key, array(), 300);
        }
        return $res;
    }

    public function getCategoryType($cat)
    {
        $type = array();
        $attr = Model_Category::one(array('nm_en' => (string)$cat));
        $id = $attr->_id;
        
        $attr = Model_Category::all(array('path' => array('$size' => 1), 'path' => new MongoId($id)))->sort(array('nm_en' => 1));
        $type[''] = 'All';
        foreach($attr as $k => $loc) {
            $path = $loc->path;
            if ((!empty($path[2])) & ($loc->category_search_list == 1)) {
                $type[(string) $loc->_id] = $loc->nm_en;
            }
        }
        return $type;
    }
    
    public function getSolrDocument()
    {
        $document = new Apache_Solr_Document();
        $document->id = (string) $this->_id; //or something else suitably unique
        $document->type_obj = self::TYPE;
        $document->type_obj_s = 'category';
        $document->status   = 1;

        $document->title    = $this->name;
        $document->url      = $this->url();
        $document->level    = count($this->path);

        foreach($this->path as $id) {
            $document->addField('category', (string)$id);
        }

        return $document;
    }

    public function getRedisPopularKey()
    {
        return APPLICATION_ENV.'sl_category_popular_' . (string)$this->_id;
    }

    public function getPopularListing($limit = self::LISTING_POPULAR_LIMIT)
    {
        //new way will use sorted list in redis
        $list_name = $this->getRedisPopularKey();
        $redis = Zend_Registry::get('redis');
        
        //try to get the latest element from the list
        $list = $redis->zRevRangeByScore($list_name, time(), '-inf', array('withscores' => TRUE, 'limit' => array(0, $limit)));

        if (empty($list)) {
            //fill up the list with old fashion way
            $key = 'category_popular_listing_children_' . (string)$this->_id;
            $cache = Zend_Registry::get('cache');
            if ($cache->test($key)) {
               $arr = $cache->load($key);
            } else {
                $children = $this->getChildren(true);
                $arr = array();
                foreach($children as $child) {
                    $arr[] = $child->_id;
                }
                $cache->save($arr, $key, array(), 300);
            }

            if ($this->id == 'mc55' || $this->id == 'mc49') { //car or property
                $result = Model_Listing::allSimple(array('ca' => array('$in' => $arr), 'phc' => array('$gt' => 0), 'sa' => Model_Listing::STATUS_PUBLISHED), array('p_dt'))->sort(array('nv' => -1))->limit($limit);
            } else {
                $result = Model_Listing::allSimple(array('ca' => array('$in' => $arr), 'sa' => Model_Listing::STATUS_PUBLISHED), array('p_dt'))->sort(array('nv' => -1))->limit($limit);
            }

            $list = array();
            foreach($result as $key) {
                $redis->zAdd($list_name, $key['p_dt']->sec, (string)$key['_id']);
                $list[(string)$key['_id']] = 1;
            }
        }

        $res = array();
        foreach($list as $key => $score) {
            $res[] = Model_Listing::find($key);
        }    
        return $res;

    }

    public function getPopularCompany($limit = 5)
    {
        $list = Model_Company::all(array('st' => 1));
        if (!empty($list)) {
            $arr = array();
            foreach($list->sort(array('cfe' => -1))->limit($limit) as $child) {
                $arr[] = $child;
            }
            return $arr;
        }
    }


    public function getRedisRecentKey()
    {
        return APPLICATION_ENV.'-sl_category_recent_' . (string)$this->_id;
    }

    public function getMostRecentListing($limit = self::LISTING_RECENT_LIMIT)
    {
        //new way will use sorted list in redis
        $list_name = $this->getRedisRecentKey();
        $redis = Zend_Registry::get('redis');
 
        //try to get the latest element from the list
        $list = $redis->zRevRangeByScore($list_name, time(), '-inf', array('withscores' => TRUE, 'limit' => array(0, $limit)));
		
        if (empty($list)) {
            //fill up the list with old fashion way
			$key = 'category_recent_listing_children_' . (string)$this->_id;
            $cache = Zend_Registry::get('cache');
            if ($cache->test($key)) {
               $arr = $cache->load($key);
            } else {
                $children = $this->getChildren(true);
                $arr = array();
                foreach($children as $child) {
                    $arr[] = $child->_id;
                }
                $cache->save($arr, $key, array(), 300);
            }

            if ($this->id == 'mc55' || $this->id == 'mc49') { //car or property
                $result = Model_Listing::allSimple(array('ca' => array('$in' => $arr), 'phc' => array('$gt' => 0), 'sa' => Model_Listing::STATUS_PUBLISHED), array('p_dt'))->sort(array('nv' => -1))->limit($limit);
            } else {
                $result = Model_Listing::allSimple(array('ca' => array('$in' => $arr), 'sa' => Model_Listing::STATUS_PUBLISHED), array('p_dt'))->sort(array('nv' => -1))->limit($limit);
            }

            $list = array();
            foreach($result as $key) {
                $redis->zAdd($list_name, $key['p_dt']->sec, (string)$key['_id']);
                $list[(string)$key['_id']] = 1;
            }
        }
        $res = array();
        foreach($list as $key => $score) {
            $res[] = Model_Listing::find($key);
        }
        return $res;
    }
	
	public static function getLatestListing($limit = 5)
    {
        $key = 'category_popular_listing_children_' . (string)$this->_id;
        $cache = Zend_Registry::get('cache');
        if ($cache->test($key)) {
           $arr = $cache->load($key);
        } else {
            $children = $this->getChildren(true);
            $arr = array();
            foreach($children as $child) {
                $arr[] = $child->_id;
            }
            $cache->save($arr, $key, array(), 300);
        }

        if ($this->id == 'mc55' || $this->id == 'mc49') { //car or property
            $result = Model_Listing::all(array('ca' => array('$in' => $arr), 'phc' => array('$gt' => 0), 'sa' => Model_Listing::STATUS_PUBLISHED, 'so' => array('$ne' => 6)))->sort(array('p_dt' => -1))->limit($limit);
        } else {
        	if($this->id == 'mc52'){
				$result = Model_Company::all(array('st' => Model_Company::STATUS_ACTIVE, 'un' => array('$exists' => true)))->sort(array('c_dt' => -1))->limit($limit);
			} else{
				$result = Model_Listing::all(array('ca' => array('$in' => $arr), 'sa' => Model_Listing::STATUS_PUBLISHED, 'so' => array('$ne' => 6)))->sort(array('p_dt' => -1))->limit($limit);	
			}
        }
        return $result;
    }
/*	
    public static function all(array $query = array())
    {
        $q  = array();
        $ts = static::$_transcript;
        $ts = array_flip($ts);
        foreach ($query as $k => $v) {
            if (isset($ts[$k])) {
                $q[$ts[$k]] = $v;
            } else {
                $q[$k] = $v;
            }
        }


        //from Shanty
        $query = $q;
		$inheritance = static::getCollectionInheritance();
		if (count($inheritance) > 1) {
			$query['_type'] = $inheritance[1]; //get the top and not the custom
		}
		$cursor = static::getMongoCollection(false)->find($query);

		$config = array();
		$config['connectionGroup'] = static::getConnectionGroupName();
		$config['db'] = static::getDbName();
		$config['collection'] = static::getCollectionName();
		$config['documentClass'] = static::getDocumentClass();
		$config['documentSetClass'] = static::getDocumentSetClass();

		return new Shanty_Mongo_Iterator_Cursor($cursor, $config);
    }

    public static function one(array $query = array())
    {
        $q  = array();
        $ts = static::$_transcript;
        $ts = array_flip($ts);
        foreach ($query as $k => $v) {
            if (isset($ts[$k])) {
                $q[$ts[$k]] = $v;
            } else {
                $q[$k] = $v;
            }
        }

        //from Shanty
        $query = $q;
		$inheritance = static::getCollectionInheritance();
		if (count($inheritance) > 1) {
			$query['_type'] = $inheritance[1]; //get the top and not the custom
		}

		$data = static::getMongoCollection(false)->findOne($query);

		if (is_null($data)) return null;

		return static::create($data, false);
    }
*/
    public function getQuickSearchTabs()
    {
        return array('');
    }

    public function getQuickSearchForms()
    {
        return array(
            new Category_Form_QuickSearchRegularForm(array('category' => $this)),
            );
    }
    
    public function getDistinctUser($limit = 5)
    {
    	$result = array();
        $key = 'category_popular_listing_children_' . (string)$this->_id;
        $cache = Zend_Registry::get('cache');
        if ($cache->test($key)) {
           $arr = $cache->load($key);
        } else {
            $children = $this->getChildren(true);
            $arr = array();
            foreach($children as $child) {
                $arr[] = $child->_id;
            }
            $cache->save($arr, $key, array(), 300);
        }

    	if($this->id == 'mc52'){
			$result = Model_Company::all(array('st' => Model_Company::STATUS_ACTIVE, 'cn' => array('$exists' => true), 'im' => array('$exists' => true)))->sort(array('c_dt' => -1))->limit($limit);
		} else{
			$results = Model_Listing::all(array('ca' => array('$in' => $arr), 'sa' => Model_Listing::STATUS_PUBLISHED))->sort(array('nv' => -1))->limit(100);
			$i = 0;
			$temp_arr = array();
			foreach($results as $new_user){
				if(!empty($new_user->user->cid)){
                    /*
					if(empty($new_user->user->company->image)){
						continue;	
					}*/
				}else{
                    /*
					if(empty($new_user->user->pp)){
						continue;	
					}
                    */
				}
				if(!in_array((string)$new_user->user->_id, $temp_arr)){
					$temp_arr[] = (string)$new_user->user->_id;
					$result[] = $new_user;
					$i++;
					if($i == $limit){
						break;
					}
				}
			}
		}
    
        return $result;
    }

    public function exportRest()
    {
        return array(
            'id' => (string)$this->_id,
            'name_sc' => !empty($this->name_sc) ? $this->name_sc : '',
            'listing_count' => !empty($this->listing_count) ? (string) $this->listing_count: '0',
            'has_children' => ( Model_Category::all(array('path' => $this->_id, 'sa' => 1 ))->count() > 1) ? '1' : '0',
            'has_listing'  => ( Model_Listing::all(array('ca' => $this->_id ))->count() > 1) ? '1' : '0',
        );
    }
}
